﻿// CTabDdns.cpp: 实现文件
//

#include "pch.h"
#include "DntDemo.h"
#include "afxdialogex.h"
#include "CTabDdns.h"
#include "TxtUtils.h"
#include "DntTest.h"
#define TAG	"TabDdns"


// CTabDdns 对话框

IMPLEMENT_DYNAMIC(CTabDdns, CDialogEx)

CTabDdns::CTabDdns(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_TAB_DDNS, pParent)
{

}

CTabDdns::~CTabDdns()
{
}

void CTabDdns::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CTabDdns, CDialogEx)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON_EVID, &CTabDdns::OnBnClickedButtonEvId)
	ON_BN_CLICKED(IDC_BUTTON_LOGIN, &CTabDdns::OnBnClickedButtonLogin)
	ON_BN_CLICKED(IDC_BUTTON_PING, &CTabDdns::OnBnClickedButtonPing)
END_MESSAGE_MAP()


// CTabDdns 消息处理程序


BOOL CTabDdns::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化

	ShowAccount(true);
	ShowTips();
	SetTimer(1, 300, NULL);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}
void CTabDdns::OnTimer(UINT_PTR nIDEvent) {
	TIME_INFO tinf;
	CString text = L"还没有";
	if (DntGetLocalTime(&tinf)) {							// 获取本地时间
		char bytes[32];
		TimShowFull(bytes, sizeof(bytes), &tinf, TF_YY_MM_DD | TF_HH_MM_SS);
		WCHAR d16[32];
		TxtGbkUnicode((char*)d16, sizeof(d16), bytes);		// GBK转换到UNICODE
		text = d16;
		text = text + L" （只使用本地的tick就产生了精确的时间）";
	}
	((CStatic*)GetDlgItem(IDC_STATIC_NT))->SetWindowText(L" 网络时间: " + text);

	//DNT_INFO* dnti = DntGetInfo();
	//text.Format(L"Save:%d Cnt:%d Retry:%d Sync:%d Busy:%04x Busy:%04x", dnti->TimerSave, dnti->TimerCnt, dnti->TimerRetry, dnti->TimerSync, mpDNT->BusyFlag, mpDNT->IdleFlag);
	//((CStatic*)GetDlgItem(IDC_STATIC_NT))->SetWindowText(text);

	CDialogEx::OnTimer(nIDEvent);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

void CTabDdns::ShowAccount(bool init) {
	char bytes[100];
	DbsGetMemText(bytes, sizeof(bytes), "an_0");
	CString name(bytes);
	DbsGetMemText(bytes, sizeof(bytes), "ap_0");
	CString psw(bytes);
	if (name != L"") {
		DbsGetMemText(bytes, sizeof(bytes), "gv_0");
		CString visit(bytes);
		CString text;
		text.Format(L"an:%s ap:%s gv:%s", name, psw, visit);
		((CEdit*)GetDlgItem(IDC_EDIT_EVID))->SetWindowText(text);
	}else if (init) {
		CString text = L"可以从云控域名服务器申请一个评估账号";
		((CEdit*)GetDlgItem(IDC_EDIT_EVID))->SetWindowText(text);
	}
	((CEdit*)GetDlgItem(IDC_EDIT_NAME))->SetWindowText(name);
	((CEdit*)GetDlgItem(IDC_EDIT_PSW))->SetWindowText(psw);

	DbsGetMemText(bytes, sizeof(bytes), "mail");
	CString mail(bytes);
	((CEdit*)GetDlgItem(IDC_EDIT_MAIL))->SetWindowText(mail);
}
void CTabDdns::ShowTips() {
	CString text;
	CString string;
	DNT_INFO* info = DntGetInfo();							// 获取DNT_INFO*

	text.Format(L"本机设置的dns共%d个", info->DnQty);
	string += text;
	uint8_t* ipv4 = (uint8_t*) &info->DnIpv4[info->DnSelect];
	text.Format(L"，当前使用[%d]%d.%d.%d.%d，云控域名服务器", info->DnSelect, ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
	string += text;

	if (info->DnIpOk) {			// 已经获取DNS的IP地址
		ipv4 = (uint8_t*)&info->SvrIpv4;
		text.Format(L"%d.%d.%d.%d:%d", ipv4[0], ipv4[1], ipv4[2], ipv4[3], info->SvrPort);
		string += text;
		text = L"，可以使用网络助手等工具使用UDP协议往这个IP及端口发送登录及心跳包指令，同时使用Wireshark等抓包工具查看UDP包";	
	}else {
		text = L"未登录";
	}
	string += text;
	((CStatic*)GetDlgItem(IDC_EDIT_TIPS))->SetWindowText(string);	
}
void CTabDdns::ShowHookCmd(char* text, bool isTx) {	
	CString string(text);
	int length = (int)strlen(text);

	ShowTips();
	if (isTx && text[0] == 'p' && text[1] == 't') {			// 发出 包类型Packet Type
		if (text[3] == 'l' && text[4] == 's') {				// 登录到服务器Login Server
			gLsTick = GetTickCount64();
			((CStatic*)GetDlgItem(IDC_EDIT_TX_LOGIN))->SetWindowText(string);
			return;
		}
		if (text[3] == 's' && text[4] == 'h') {				// 同步心跳包Sync Heartbeat
			gShTick = GetTickCount64();
			((CEdit*)GetDlgItem(IDC_EDIT_TX_SH))->SetWindowText(string);
			return;
		}
		return;
	}
	if (!isTx && text[0] == 'l' && text[1] == 's') {		// 接收 登录到服务器Login Server	
		((CEdit*)GetDlgItem(IDC_EDIT_RX_LOGIN))->SetWindowText(string);
		char* texts[8];
		int qty = TxtKeyArray((size_t*)texts, (char*)text, length, '&', 1);
		if (qty >= 3) {
			int interval = TxtToInt(texts[2]);
			string.Format(L"接收成功，心跳包间隔时间：%d秒 ，指令用时%d毫秒", interval, GetTickCount64()- gLsTick);
			((CEdit*)GetDlgItem(IDC_STATIC_LOGIN))->SetWindowText(string);
		}
		return;
	}
	if (!isTx && text[0] == 's' && text[1] == 'h') {		// 接收 同步心跳包Sync Heartbeat
		((CEdit*)GetDlgItem(IDC_EDIT_RX_SH))->SetWindowText(string);
		char* texts[8];
		int qty = TxtKeyArray((size_t*)texts, (char*)text, length, '&', 1);
		if (qty >= 3) {
			CString ipv4(texts[2]);
			string.Format(L"接收成功，本机IP地址：%s ，指令用时%d毫秒", ipv4, GetTickCount64() - gShTick);
			((CEdit*)GetDlgItem(IDC_STATIC_SH))->SetWindowText(string);
		}
		return;
	}
	//CLOGD(TAG, "ShowHookCmd  %s", text);
}


extern CTabDdns* mTabDdns;
extern "C" static void evalAcctCallback(char* text) {
	if (text != NULL) {										// 申请评估账号Evaluation Account
		int length = (int)strlen(text);
		char* texts[8];
		int qty = TxtKeyArray((size_t*)texts, (char*)text, length - 1, '&', 1);
		if (qty >= 3) {
			CLOGD(TAG, "EvaluateIdCall qty %d %d{%s}", qty, length, text);
			DbsSetMemText("an_0", texts[0]);
			DbsSetMemText("ap_0", texts[1]);
			DbsSetMemText("gv_0", texts[2]);
			if (mTabDdns != NULL) {
				mTabDdns->ShowAccount(false);
			}
			return;
		}
	}
	CLOGD(TAG, "EvaluateId Call {%s}", text);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
void CTabDdns::OnBnClickedButtonEvId() {
	char bytes[100];
	if (DbsGetMemText(bytes, sizeof(bytes), "an_0") > 0) {
		::AfxMessageBox(L"已经有评估账号，不需要再次申请");
		return;
	}
	CString mail;
	((CEdit*)GetDlgItem(IDC_EDIT_MAIL))->GetWindowText(mail);
	if (mail == L"" || mail.GetLength() < 6) {
		::AfxMessageBox(L"请输入有效的电子邮箱或手机号码");
		return;
	}
	TxtUnicodeUtf8(bytes, sizeof(bytes), (short*)mail.AllocSysString());		// UNICODE转换到GUTF8
	DbsSetMemText("mail", bytes);
	TestEvalAccount(evalAcctCallback);
}
void CTabDdns::OnBnClickedButtonLogin(){
	char bytes[128];
	CString string;
	((CEdit*)GetDlgItem(IDC_EDIT_NAME))->GetWindowText(string);
	TxtUnicodeUtf8(bytes, sizeof(bytes), (short*)string.AllocSysString());	// UNICODE转换到GUTF8
	DbsSetMemText("an_0", bytes);
	((CEdit*)GetDlgItem(IDC_EDIT_PSW))->GetWindowText(string);
	TxtUnicodeUtf8(bytes, sizeof(bytes), (short*)string.AllocSysString());	// UNICODE转换到GUTF8
	DbsSetMemText("ap_0", bytes);

	if (DbsGetMemText(bytes, sizeof(bytes), "an_0") > 0) {					// 账号不是空
		if (DbsGetMemText(bytes, sizeof(bytes), "ap_0") > 0) {				// 密码不是空
			((CStatic*)GetDlgItem(IDC_EDIT_TX_LOGIN))->SetWindowText(L"");
			((CEdit*)GetDlgItem(IDC_EDIT_TX_SH))->SetWindowText(L"");
			((CEdit*)GetDlgItem(IDC_EDIT_RX_LOGIN))->SetWindowText(L"");
			((CEdit*)GetDlgItem(IDC_STATIC_LOGIN))->SetWindowText(L"");
			((CEdit*)GetDlgItem(IDC_EDIT_RX_SH))->SetWindowText(L"");
			((CEdit*)GetDlgItem(IDC_STATIC_SH))->SetWindowText(L"");
			/*DNT_INFO* info = &mTEST.Info;
			info->State = STATE_LOGIN;*/
			DntSetIdleFlag(DNT_RB_LOGIN);
			return;
		}
		::AfxMessageBox(L"请输入动态域名的账号密码");
		return;
	}
	::AfxMessageBox(L"请输入动态域名的账号名");
}
void CTabDdns::OnBnClickedButtonPing(){
	char bytes[100];
	DbsGetMemText(bytes, sizeof(bytes), "an_0");
	CString name(bytes);
	CString text;
	text.Format(L"/K ping %s", name);
	ShellExecute(NULL, _T("open"), _T("cmd.exe"), text, NULL, SW_SHOWDEFAULT);
}
